package com.event.management.backend.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckRole;
import com.event.management.backend.util.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 文件上传控制器
 * 注意：此控制器替代了EventController中的上传功能，所有文件上传相关操作请使用此控制器
 */
@Slf4j
@RestController
@RequestMapping("/api/files")
@Api(tags = "文件上传接口", description = "提供图片上传等功能")
public class FileController {

    @Value("${file.upload.path:/uploads/images}")
    private String uploadPath;

    @Value("${file.access.path:/images}")
    private String accessPath;

    /**
     * 上传活动封面图片
     * 注意：此接口替代了EventController中的同名接口，功能完全兼容
     * @param file 封面图片文件
     * @param returnType 返回类型，可选值：simple（仅返回URL）, full（返回完整信息）
     * @return 图片相对路径或包含多种URL的Map
     */
    @ApiOperation("上传活动封面图片")
    @SaCheckRole(value = {"admin", "organizer"}, mode = cn.dev33.satoken.annotation.SaMode.OR)
    @PostMapping("/upload/cover")
    public Result<?> uploadEventCover(
            @ApiParam(value = "封面图片文件", required = true) @RequestParam("file") MultipartFile file,
            @ApiParam(value = "返回类型", required = false, allowableValues = "simple,full") 
            @RequestParam(value = "returnType", required = false, defaultValue = "full") String returnType) {
        if (file.isEmpty()) {
            return Result.error(400, "上传失败，请选择文件");
        }

        try {
            // 检查文件类型
            String contentType = file.getContentType();
            if (contentType == null || !contentType.startsWith("image/")) {
                return Result.validateFailed("只能上传图片文件");
            }
            
            // 生成文件保存路径
            String fileName = generateFileName(file.getOriginalFilename());
            
            // 从系统目录找到eventsys目录，作为根目录
            String currentDir = System.getProperty("user.dir");
            String rootDir = currentDir;
            
            // 向上查找到eventsys目录作为根目录
            File dirFile = new File(currentDir);
            while (dirFile != null && !dirFile.getName().equals("eventsys")) {
                dirFile = dirFile.getParentFile();
                if (dirFile != null) {
                    rootDir = dirFile.getAbsolutePath();
                }
            }
            
            // 使用根目录加上相对路径组成最终的绝对路径
            String relativePath = uploadPath.startsWith("/") ? uploadPath.substring(1) : uploadPath;
            String absoluteUploadPath = Paths.get(rootDir, relativePath).toString();
            
            log.info("当前项目根目录: {}", currentDir);
            log.info("eventsys根目录: {}", rootDir);
            log.info("相对上传路径: {}", relativePath);
            log.info("最终上传绝对路径: {}", absoluteUploadPath);
            
            // 确保上传目录存在
            File uploadDir = new File(absoluteUploadPath);
            if (!uploadDir.exists()) {
                boolean created = uploadDir.mkdirs();
                if (!created) {
                    log.error("无法创建上传目录: {}", absoluteUploadPath);
                    return Result.error(500, "服务器配置错误，无法创建上传目录");
                }
                log.info("成功创建上传目录: {}", absoluteUploadPath);
            }
            
            // 保存文件
            Path filePath = Paths.get(absoluteUploadPath, fileName);
            Files.write(filePath, file.getBytes());
            
            // 验证文件是否成功保存
            File savedFile = new File(filePath.toString());
            if (!savedFile.exists() || savedFile.length() == 0) {
                log.error("文件保存失败或文件大小为0: {}", filePath);
                return Result.error(500, "文件保存失败");
            }
            
            log.info("文件已成功保存: {}", filePath);
            log.info("图片访问地址: {}", accessPath + "/" + fileName + "，实际文件路径: " + filePath);
            
            // 返回访问路径 - 统一使用/images/格式
            String imageUrl = accessPath + "/" + fileName;  // 使用配置的访问路径
            
            // 根据返回类型决定返回格式
            if ("simple".equals(returnType)) {
                // 简单模式只返回图片路径
                log.info("简单模式返回图片路径: {}", imageUrl);
                return Result.success(imageUrl);
            } else {
                // 完整模式返回包含多种URL的Map
                Map<String, String> urlMap = new HashMap<>();
                urlMap.put("url", imageUrl);          // 首选URL（使用/images/格式）
                urlMap.put("fileName", fileName);     // 文件名
                urlMap.put("relativePath", accessPath.substring(1) + "/" + fileName); // 相对路径（去掉前缀/）
                
                log.info("完整模式返回图片信息: {}", urlMap);
                return Result.success(urlMap, "图片上传成功");
            }
        } catch (IOException e) {
            log.error("文件上传失败", e);
            return Result.error(500, "文件上传失败: " + e.getMessage());
        }
    }
    
    /**
     * 访问图片接口
     * 通过文件名直接访问上传的图片
     * @param fileName 文件名
     * @return 图片资源
     */
    @ApiOperation("访问图片")
    @GetMapping("/image/{fileName:.+}")
    public ResponseEntity<Resource> getImage(@PathVariable String fileName) {
        try {
            // 从系统目录找到eventsys目录，作为根目录
            String currentDir = System.getProperty("user.dir");
            String rootDir = currentDir;
            
            // 向上查找到eventsys目录作为根目录
            File dirFile = new File(currentDir);
            while (dirFile != null && !dirFile.getName().equals("eventsys")) {
                dirFile = dirFile.getParentFile();
                if (dirFile != null) {
                    rootDir = dirFile.getAbsolutePath();
                }
            }
            
            // 使用根目录加上相对路径组成最终的绝对路径
            String relativePath = uploadPath.startsWith("/") ? uploadPath.substring(1) : uploadPath;
            String absoluteUploadPath = Paths.get(rootDir, relativePath).toString();
            
            // 构建文件路径
            Path filePath = Paths.get(absoluteUploadPath, fileName);
            File file = filePath.toFile();
            
            log.info("请求图片: {}", fileName);
            log.info("图片路径: {}", filePath);
            
            // 检查文件是否存在
            if (!file.exists() || !file.isFile()) {
                log.error("图片文件不存在: {}", filePath);
                return ResponseEntity.notFound().build();
            }
            
            // 根据文件扩展名确定内容类型
            String contentType = determineContentType(file);
            
            // 创建资源
            FileSystemResource resource = new FileSystemResource(file);
            
            return ResponseEntity.ok()
                    .contentType(MediaType.parseMediaType(contentType))
                    .header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + file.getName() + "\"")
                    .body(resource);
        } catch (Exception e) {
            log.error("读取图片失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    /**
     * 根据文件扩展名确定内容类型
     */
    private String determineContentType(File file) {
        String fileName = file.getName().toLowerCase();
        
        try {
            // 尝试使用Files.probeContentType
            String contentType = Files.probeContentType(file.toPath());
            if (contentType != null) {
                return contentType;
            }
        } catch (IOException e) {
            log.warn("无法确定文件类型: {}", file);
        }
        
        // 根据文件扩展名判断
        if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) {
            return "image/jpeg";
        } else if (fileName.endsWith(".png")) {
            return "image/png";
        } else if (fileName.endsWith(".gif")) {
            return "image/gif";
        } else if (fileName.endsWith(".svg")) {
            return "image/svg+xml";
        } else if (fileName.endsWith(".webp")) {
            return "image/webp";
        }
        
        // 默认为二进制流
        return "application/octet-stream";
    }
    
    /**
     * 生成唯一的文件名
     * @param originalFilename 原始文件名
     * @return 生成的唯一文件名
     */
    private String generateFileName(String originalFilename) {
        // 获取文件扩展名
        String extension = "";
        if (originalFilename != null && originalFilename.contains(".")) {
            extension = originalFilename.substring(originalFilename.lastIndexOf("."));
        } else {
            // 如果没有扩展名，默认为.jpg
            extension = ".jpg";
        }
        
        // 生成日期前缀
        String datePrefix = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
        
        // 生成UUID
        String uuid = UUID.randomUUID().toString().substring(0, 8);
        
        // 返回格式：yyyyMMdd_HHmmss_uuid.ext
        return datePrefix + "_" + uuid + extension;
    }
} 